package com.object.aop;

import cn.dev33.satoken.stp.StpUtil;
import com.google.gson.Gson;
import com.object.ip.IpUtil;
import com.object.utils.AsyncUtil;
import lombok.extern.slf4j.Slf4j;
import com.object.module.lq.sys.entity.TLogEntity;
import com.object.module.lq.sys.service.TLogService;
import com.object.utils.OnlineTools;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.util.ContentCachingRequestWrapper;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.Map;


/**
 * 日志记录aop
 */
@Configuration
//切面类
@Aspect
@Slf4j
@Profile("prod")
//生产环境才记录系统日志
public class LogAop {
    @Resource
    private TLogService logService;

    @Pointcut("execution(public * com.object.module.lq.sys.controller.*.*(..))")
    public void log() {
    }

    @Around("log()")
    public Object around(ProceedingJoinPoint joinPoint) {
        //  System.out.println("前置通知");
        long beginTime = System.currentTimeMillis();
        Object proceed = null;
        try {
            // System.out.println("后值通知");
            proceed = joinPoint.proceed();
        } catch (Throwable throwable) {
            //throwable.printStackTrace();
            //System.out.println("异常通知");
        } finally {
            long time = System.currentTimeMillis() - beginTime;
            //System.out.println("最终通知");
            RequestAttributes ra = RequestContextHolder.getRequestAttributes();
            ServletRequestAttributes sra = (ServletRequestAttributes) ra;
            HttpServletRequest request = sra.getRequest();
            //异步执行
            Map<String, String[]> paramsMap = request.getParameterMap();
            String params = new Gson().toJson(paramsMap);

            TLogEntity sysLogEntity = new TLogEntity();
            // 获取 URL 和 IP
            sysLogEntity.setUrl(request.getRequestURI());
            sysLogEntity.setIp(request.getHeader("ipaddress"));

            sysLogEntity.setUserName(StpUtil.getLoginIdAsString());
            sysLogEntity.setParams(params);
            AsyncUtil.executeSysTask(() -> {
                saveLog(joinPoint, time, sysLogEntity, logService);
            });
        }
        return proceed;

    }

    private void saveLog(ProceedingJoinPoint joinPoint, long time, TLogEntity sysLogEntity, TLogService logService) {

        // 设置执行时间
        sysLogEntity.setExeuTime((time / 1000.0) + "秒");
        sysLogEntity.setCreateTime(new Date());

        // 获取类名、方法名
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = ((MethodSignature) joinPoint.getSignature()).getName();
        sysLogEntity.setClassName(className);
        sysLogEntity.setMethodName(methodName);
        sysLogEntity.setIp(IpUtil.getIpAddress(sysLogEntity.getIp()).getInfo());

        logService.save(sysLogEntity);
    }


}
